/***********************************************************************************************************************
*                                                                                                                      *
* SPLASH build system v0.1                                                                                             *
*                                                                                                                      *
* Copyright (c) 2013 Andrew D. Zonenberg                                                                               *
* All rights reserved.                                                                                                 *
*                                                                                                                      *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the     *
* following conditions are met:                                                                                        *
*                                                                                                                      *
*    * Redistributions of source code must retain the above copyright notice, this list of conditions, and the         *
*      following disclaimer.                                                                                           *
*                                                                                                                      *
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the       *
*      following disclaimer in the documentation and/or other materials provided with the distribution.                *
*                                                                                                                      *
*    * Neither the name of the author nor the names of any contributors may be used to endorse or promote products     *
*      derived from this software without specific prior written permission.                                           *
*                                                                                                                      *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR       *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
* POSSIBILITY OF SUCH DAMAGE.                                                                                          *
*                                                                                                                      *
***********************************************************************************************************************/

#ifndef ToolFlags_h
#define ToolFlags_h

/**
	@brief Generic representation of a compiler toolchain
 */
class Toolchain
{
public:
	Toolchain()
	{}
	
	virtual ~Toolchain()
	{}
	
	///@brief Returns a human-readable description of the toolchain (ex: "g++ (Debian 4.7.2-5) 4.7.2")
	virtual std::string GetDescription() const =0;
	
	///@brief Returns a SHA256 hash uniquely identifying this toolchain version
	virtual std::string GetHash() const =0;
};

/**
	@brief Generic representation of a single flag to a build tool
 */
template<class T> class BuildFlag
{
public:
	BuildFlag()
	{}
	
	virtual ~BuildFlag()
	{}
	
	virtual BuildFlag<T>* Clone() const =0;
	virtual std::string toString(const T* toolchain) =0;
};

/**
	@brief List of build flags
 */
template<class T> class BuildFlagList
{
public:
	BuildFlagList()
	{}
	
	BuildFlagList(const BuildFlagList<T>& rhs)
	{
		*this = rhs;
	}
	
	BuildFlagList<T>& operator=(const BuildFlagList<T>& rhs)
	{
		//Clean out all of our existing flags
		for(size_t i=0; i<m_flags.size(); i++)
			delete m_flags[i];
		m_flags.clear();
		
		//Add new ones
		for(size_t i=0; i<rhs.m_flags.size(); i++)
			m_flags.push_back(rhs.m_flags[i]->Clone());
		
		return *this;
	}
	
	virtual ~BuildFlagList()
	{
		for(size_t i=0; i<m_flags.size(); i++)
			delete m_flags[i];
		m_flags.clear();
	}
	
	/**
		@brief Adds a flag. The pointer will be freed by the destructor.
	 */
	void push_back(T* flag)
	{ m_flags.push_back(flag); }
	
	size_t size() const
	{ return m_flags.size(); }
	
	T* operator[](size_t i) const
	{ return m_flags[i]; }
	
protected:
	std::vector<T*> m_flags;
};

#endif
